package com.picket.dao;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;

import org.springframework.orm.jdo.support.JdoDaoSupport;
import org.springframework.stereotype.Repository;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.picket.domain.Match;
import com.picket.domain.UserPrediction;
 
@Repository
public class UserPredictionDao extends JdoDaoSupport implements IUserPredictionDao {
 

  
 @Override
 public void create(final List<UserPrediction> userpredictions) {
	 for(UserPrediction userprediction : userpredictions){
		  getJdoTemplate().makePersistent(userprediction);
		  System.out.println(userprediction.getKey());
	 }

 }
 
 @Override
 public Collection<UserPrediction> getAllUserPredictions() {
 
  final PersistenceManager pm = getPersistenceManager();
   
  try {
 
   final Query query = pm.newQuery(UserPrediction.class);
   query.setOrdering("matchNo ascending");
    
   @SuppressWarnings("unchecked")
   final Collection<UserPrediction> userpredictions =
    (Collection<UserPrediction>) query.execute();
    
   return pm.detachCopyAll((Collection<UserPrediction>)userpredictions);
  }
   
  finally {
   releasePersistenceManager(pm);
  }
 
 }
 /*
 @Override
 public Collection<UserPrediction> getAllUserPredictionsForEvent(long eventId) {
 
  final PersistenceManager pm = getPersistenceManager();
   
  try {
 
   final Query query = pm.newQuery(UserPrediction.class);
   query.setFilter("eventId == eventIdParam");
   query.setOrdering("matchNo ascending");
   query.declareParameters("long eventIdParam"); 
   @SuppressWarnings("unchecked")
   final Collection<UserPrediction> userpredictions =
    (Collection<UserPrediction>) query.execute(eventId);
    
   return pm.detachCopyAll((Collection<UserPrediction>)userpredictions);
  }
   
  finally {
   releasePersistenceManager(pm);
  }
 
 }*/
 @Override
 public UserPrediction getUserPrediction(long id) {
 
  final PersistenceManager pm = getPersistenceManager();
   
  try {
	  
	  Key k = KeyFactory.createKey(UserPrediction.class.getSimpleName(), id);
      return pm.getObjectById(UserPrediction.class, k);

  }
   
  finally {
   releasePersistenceManager(pm);
  }
 
 }
 
 @Override
 public Collection<UserPrediction> getAllUserPredictionsForUserPool(long userPoolId) {
 
  final PersistenceManager pm = getPersistenceManager();
   
  try {
 
   final Query query = pm.newQuery(UserPrediction.class);
   query.setFilter("userPoolId == userPoolIdParam");
   query.setOrdering("userEmail ascending");
   query.declareParameters("long userPoolIdParam"); 
   @SuppressWarnings("unchecked")
   final Collection<UserPrediction> userpredictions =
    (Collection<UserPrediction>) query.execute(userPoolId);
    
   return pm.detachCopyAll((Collection<UserPrediction>)userpredictions);
  }
   
  finally {
   releasePersistenceManager(pm);
  }
 
 }
 
 @Override
 @SuppressWarnings("unchecked")
 public Collection<UserPrediction> getAllUserPredictionsForUserPoolOrderedByMatchNo(long userPoolId) {
 
  final PersistenceManager pm = getPersistenceManager();
   
  try {
	   Query query = pm.newQuery(UserPrediction.class);
	   query.setFilter("userPoolId == userPoolIdParam");
	   query.setOrdering("matchNo ascending");
	   query.declareParameters("long userPoolIdParam"); 
	   Collection<UserPrediction> userpredictions =
	    (Collection<UserPrediction>) query.execute(userPoolId);
    
   return pm.detachCopyAll((Collection<UserPrediction>)userpredictions);
  }
   
  finally {
   releasePersistenceManager(pm);
  }
 
 }
	private void updatePrediction(long id, String updatedPrediction) {
		PersistenceManager pm = getPersistenceManager();
		UserPrediction prediction = null;

		try {
			pm.currentTransaction().begin();
			// We don't have a reference to the selected Product.
			// So we have to look it up first,
			Key k = KeyFactory.createKey(UserPrediction.class.getSimpleName(),
					id);
			prediction = pm.getObjectById(UserPrediction.class, k);
			prediction.setMatchPrediction(updatedPrediction);
			pm.makePersistent(prediction);
			pm.currentTransaction().commit();
		} catch (Exception ex) {
			pm.currentTransaction().rollback();
			throw new RuntimeException(ex);
		} finally {
			pm.close();
		}
	}

 @Override
 public Collection<UserPrediction> updatePredictions(List<String> userPredictions, long userPoolId) throws Exception{
	 Collection<UserPrediction> userPreds = getAllUserPredictionsForUserPoolOrderedByMatchNo(userPoolId);
	 Collection<UserPrediction> toBePredicted = new ArrayList<UserPrediction>(); 
	 Calendar currentDateTime = Calendar.getInstance();
	 for(UserPrediction userPred:userPreds){
			if(!isHistory(currentDateTime.getTime(),userPred.getMatchDateTime())){
				toBePredicted.add(userPred);
			}
		}
		if(toBePredicted.size()!=userPredictions.size()){
			throw new Exception("Array Size not equal.");
		}
		
	

	 int index=0;
	 for(UserPrediction pred:toBePredicted){
		 updatePrediction(pred.getId(),userPredictions.get(index++));
	 }

	 return getAllUserPredictionsForUserPool(userPoolId);
 }
 
private boolean isHistory(Date currentDateTime,
		Date matchDateTimeAsCalendar) {
	return currentDateTime.after(matchDateTimeAsCalendar);
}

 @Override
 public Collection<UserPrediction> getAllUserPredictionsForMatrix(long matchId) {
 
  final PersistenceManager pm = getPersistenceManager();
   
  try {
 
   final Query query = pm.newQuery(UserPrediction.class);
   query.setFilter("matchId == matchIdParam");
   query.setOrdering("userEmail ascending");
   query.declareParameters("long matchIdParam"); 
   @SuppressWarnings("unchecked")
   final Collection<UserPrediction> userpredictions =
    (Collection<UserPrediction>) query.execute(matchId);
    
   return pm.detachCopyAll((Collection<UserPrediction>)userpredictions);
  }
   
  finally {
   releasePersistenceManager(pm);
  }
 
 }

 private Collection<UserPrediction> getAllUserPredictionsForMatch(long matchId) {
	 
	  final PersistenceManager pm = getPersistenceManager();
	   
	  try {
	 
	   final Query query = pm.newQuery(UserPrediction.class);
	   query.setFilter("matchId == matchIdParam");
	   query.setOrdering("userPoolId,matchNo ascending");
	   query.declareParameters("long matchIdParam"); 
	   @SuppressWarnings("unchecked")
	   final Collection<UserPrediction> userpredictions =
	    (Collection<UserPrediction>) query.execute(matchId);
	    
	   return pm.detachCopyAll((Collection<UserPrediction>)userpredictions);
	  }
	   
	  finally {
	   releasePersistenceManager(pm);
	  }
	 
	 }
 
 @Override
 public void  updatePredictionsWithPoints(Match match){
	 Collection<UserPrediction> userPreds = getAllUserPredictionsForMatch(match.getId());
	 for(UserPrediction pred:userPreds){
		 updatePredictionWithPoints(pred.getId(),match);
	 }

	// return getAllUserPredictionsForEvent(match.getEventId());
 }
 
	private void updatePredictionWithPoints(long id, Match match) {
		PersistenceManager pm = getPersistenceManager();
		UserPrediction prediction = null;

		try {
			pm.currentTransaction().begin();
			// We don't have a reference to the selected Product.
			// So we have to look it up first,
			Key k = KeyFactory.createKey(UserPrediction.class.getSimpleName(),
					id);
			prediction = pm.getObjectById(UserPrediction.class, k);
			
			if(prediction.getMatchPrediction().equalsIgnoreCase(match.getMatchOutcome())){
				prediction.setPredictionPoints(match.getMatchOutcomePts());
			}else{
				prediction.setPredictionPoints(0);
			}
			
			pm.makePersistent(prediction);
			pm.currentTransaction().commit();
		} catch (Exception ex) {
			pm.currentTransaction().rollback();
			throw new RuntimeException(ex);
		} finally {
			pm.close();
		}
	} 
 
}